package arithmetic;

import java.io.IOException;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.Lists;
import com.google.gson.Gson;

import lombok.Data;

/**
 * @author jiangfeng on 2022/3/3
 */
@Data
public class FieldValue {
    /**
     * 结论: 数组类似是引用类型反序列化必须带上字段名:.
     */

    /**
     * 精确值, 可用于精确/模糊匹配
     */
    private String strValue;

    /**
     * 数值
     */
    private Double numValue;

    /**
     * 布尔值
     */
    private Boolean boolValue;
    /**
     * 日期
     */
    private LocalDateTime dateValue;

    /**
     * 精确值列表
     */
    private List<String> strValues;

    /**
     * 数值列表
     */
    private List<Double> numValues;

    /**
     * 日期列表 适用
     */
    private List<LocalDateTime> dateValues;

    public FieldValue() {
    }

    public FieldValue(String strValue) {
        this.strValue = strValue;
    }

    public FieldValue(Boolean boolValue) {
        this.boolValue = boolValue;
    }

    public FieldValue(Double numValue) {
        this.numValue = numValue;
    }

    public FieldValue(LocalDateTime dateValue) {
        this.dateValue = dateValue;
    }

   /* public FieldValue(String... strValue) {
        if (strValue.length == 1) {
            this.strValue = strValue[0];
        } else if (strValue.length > 1) {
            this.strValues = Lists.newArrayList(strValue);
        }
    }*/
   /* public FieldValue(Long... numValue) {
        if (numValue.length == 1) {
            this.numValue = numValue[0];
        } else if (numValue.length > 1) {
            this.numValues = Lists.newArrayList(numValue);
        }
    }*/


    public FieldValue(Double[] values) {
        this.numValues = Lists.newArrayList(values);
    }

    public FieldValue(String[] values) {
        this.strValues = Lists.newArrayList(values);
    }

    public FieldValue(List<String> values) {
        if (values == null || values.size() < 1) {
            return;
        }
        Object o = values.get(0);
        if (o instanceof String) {
            this.strValues = Lists.newArrayList(values);
            return;
        }

    }

   /* public FieldValue(List values) {
        if (values == null || values.size() < 1) {
            return;
        }
        Object o = values.get(0);
        if (o instanceof String) {
            this.strValues = Lists.newArrayList(values);
            return;
        }
        if (o instanceof Long) {
            this.numValues = Lists.newArrayList(values);
            return;
        }
        if (o instanceof BigDecimal) {
            this.bigNumValues = Lists.newArrayList(values);
            return;
        }
        if (o instanceof LocalDateTime) {
            this.dateValues = Lists.newArrayList(values);
        }
    }*/


    public FieldValue(LocalDateTime... dateValue) {
        if (dateValue.length == 1) {
            this.dateValue = dateValue[0];
        } else if (dateValue.length > 1) {
            this.dateValues = Lists.newArrayList(dateValue);
        }
    }


    public static FieldValue of(String... value) {
        if (value.length == 1) {
            return new FieldValue(value[0]);
        }
        return new FieldValue(value);
    }

    public static FieldValue of(Double... value) {
        if (value.length == 1) {
            return new FieldValue(value[0]);
        }
        return new FieldValue(value);
    }

    public static FieldValue of(LocalDateTime... value) {
        return new FieldValue(value);
    }

    public static FieldValue of(Boolean value) {
        return new FieldValue(value);
    }

    public final static String SPLIT = ",";

    @Override
    public String toString() {
        // Stream.of(strValue, numValue, dataValue, strValues, numValues, dataValues).filter(Objects::nonNull)
        // .findFirst()
        if (strValue != null) {
            return strValue;
        }
        if (numValue != null) {
            return numValue.toString();
        }

            /*if(dateValue !=null){
                // es 时间格式:  yyyy-MM-dd'T'hh:mm:ss.SSS 例: 2022-03-02T20:00:29.372
                // es 日期格式:  yyyy-MM-dd 例2022-03-02
                return DATE_TIME.format(dateValue);
            }
            if(strValues!=null){
                return String.join(SPLIT,strValues);
            }
            if(dateValues !=null){
                // es 时间格式:  2022-03-02T20:00:29.372  yyyy-MM-dd'T'hh:mm:ss.SSS
                // es 日期格式:  2022-03-02  yyyy-MM-dd
                return dateValues.stream().map(DATE_TIME::format).collect(Collectors.joining(SPLIT));
            }*/
        if (numValues != null) {
            return numValues.stream().map(Object::toString).collect(Collectors.joining(SPLIT));
        }

        return null;
    }

    /**
     * test
     */
    public static void main(String[] args) throws IOException {
        System.out.println(new FieldValue("F"));
        //        System.out.println(new FieldValue("F","A"));
        System.out.println(new FieldValue(1.3D));
        System.out.println(FieldValue.of(1D,2.2D));
        System.out.println(new FieldValue(LocalDateTime.now()));
        System.out.println(new FieldValue(LocalDateTime.now(),LocalDateTime.now().minusDays(1L)));

        ObjectMapper objectMapper = new ObjectMapper();

      /* String  a = "{\n"
               + "        \"operator\": \"EQUAL\",\n"
               + "        \"fieldName\": \"dataVersion\",\n"
               + "        \"fieldValue\": [\"2022030117\",\"1\"]\n"
               + "      }";

       GeneralFilter fieldValue = objectMapper.readValue(a, GeneralFilter.class);
       System.out.println(fieldValue);*/

        String c = "{\"a\":[\"2\",\"1\"]}";
        Teset c1 = objectMapper.readValue(c, Teset.class);
        System.out.println(c1);

        String d = "\"E\"";
        Teset d1 = objectMapper.readValue(d, Teset.class);
        System.out.println(d1);

        try {
            String e = "[\"E\"]";
            Teset e1 = objectMapper.readValue(e, Teset.class);
            System.out.println(e1);
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }

        try {
            String e = "1.2";
            Teset e1 = objectMapper.readValue(e, Teset.class);
            System.out.println(e1);
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }

        try {
            String b = "[\"2022030117\",\"1\"]";
            FieldValue fieldValue = objectMapper.readValue(b, FieldValue.class);
            System.out.println(fieldValue);
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }

        try {
            String b = "[\"2022030117\",\"1\"]";
            //FieldValue fieldValue = objectMapper.readValue(b, new TypeReference<FieldValue>(){});

            FieldValue fieldValue =  new Gson().fromJson(b, FieldValue.class);
            System.out.println(fieldValue);
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }

    @Data
    static class Teset {
        List<String> a;

        public Teset(Double c) {
            this.c = c;
        }

        Double c;



        public Teset(String b) {
            this.b = b;
        }



        String b;

        public Teset(){}

        public Teset(List<String> a) {
            this.a = a;
        }
    }

}

